package com.atguigu.gmall.order.service.impl;

import com.atguigu.gmall.cart.client.CartFeignClient;
import com.atguigu.gmall.common.config.constant.MqConst;
import com.atguigu.gmall.common.config.service.RabbitService;
import com.atguigu.gmall.common.util.HttpClientUtil;
import com.atguigu.gmall.model.enums.OrderStatus;
import com.atguigu.gmall.model.enums.PaymentWay;
import com.atguigu.gmall.model.enums.ProcessStatus;
import com.atguigu.gmall.model.order.OrderDetail;
import com.atguigu.gmall.model.order.OrderInfo;
import com.atguigu.gmall.order.mapper.OrderDetailMapper;
import com.atguigu.gmall.order.mapper.OrderInfoMapper;
import com.atguigu.gmall.order.service.OrderService;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.*;

@Service
public class OrderServiceImpl extends ServiceImpl<OrderInfoMapper , OrderInfo> implements OrderService{
    @Autowired
    private OrderInfoMapper orderInfoMapper;

    @Autowired
    private OrderDetailMapper orderDetailMapper;

    @Autowired
    private RedisTemplate redisTemplate;

    @Autowired
    private CartFeignClient cartFeignClient;

    @Autowired
    private RabbitService rabbitService;

    @Value("${ware.url}")
    private String wareUrl;  // http://localhost:9001

    @Override
    public String getTradeNo(String userId) {
        //  这个就是流水号！
        String tradeNo = UUID.randomUUID().toString();
        //  定义Key
        String key = "tradeNoKey:" + userId;
        //  存储到缓存中：
        this.redisTemplate.opsForValue().set(key, tradeNo);

        return tradeNo;
    }

    @Override
    public Boolean checkTradeNo(String tradeNo, String userId) {
        //  获取到缓存的流水号
        //  定义Key
        String key ="tradeNoKey:"+userId;
        String redisTradeNo = (String) this.redisTemplate.opsForValue().get(key);
        //  返回比较结果
        return tradeNo.equals(redisTradeNo);
    }

    @Override
    public void delTradeNo(String userId) {
        //  定义Key
        String key ="tradeNoKey:"+userId;
        this.redisTemplate.delete(key);
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public Long saveOrderInfo(OrderInfo orderInfo) {
        //插入到orderInfo表
        //  细节：total_amount，order_status,user_id,out_trade_no,trade_body,operate_time,expire_time,process_status
        orderInfo.sumTotalAmount();
        orderInfo.setOrderStatus(OrderStatus.UNPAID.name());
        String outTradeNo = "ATGUIGU" + System.currentTimeMillis() + "" + new Random().nextInt(1000);
        //第三方订单编号
        orderInfo.setOutTradeNo(outTradeNo);
        orderInfo.setTradeBody("结婚买房买车买手机.");
        //  将所有的商品名称进行拼接！
        orderInfo.setOperateTime(new Date());
        //  自己赋值支付方式！
        orderInfo.setPaymentWay(PaymentWay.ONLINE.name());
        Calendar calendar = Calendar.getInstance();
        calendar.add(Calendar.DATE,1);
        orderInfo.setExpireTime(calendar.getTime()); // +1天
        //  在订单的进度状态中能够获取到订单状态！
        orderInfo.setProcessStatus(ProcessStatus.UNPAID.name());
        orderInfoMapper.insert(orderInfo);
        //  插入数据到orderDetail表
        List<OrderDetail> orderDetailList = orderInfo.getOrderDetailList();
        orderDetailList.stream().forEach((orderDetail -> {
            //  赋值订单Id
            orderDetail.setOrderId(orderInfo.getId());
            orderDetailMapper.insert(orderDetail);
        }));

        //  删除购物车数据！
          cartFeignClient.delCart(orderInfo.getUserId().toString());
        Long orderId = orderInfo.getId();

        //发送一个消息到延迟队列  定时取消订单
        this.rabbitService.sendDelayMessage(MqConst.EXCHANGE_DIRECT_ORDER_CANCEL,MqConst.ROUTING_ORDER_CANCEL,orderId,MqConst.DELAY_TIME);

        return orderId;
    }

    @Override
    public Boolean checkStock(Long skuId, Integer skuNum) {
        //  http://localhost:9001/hasStock/?skuId=10221&num=2
        String result = HttpClientUtil.doGet(wareUrl + "/hasStock/?skuId=" + skuId + "&num=" + skuNum);
        //  返回结果
        return "1".equals(result);
    }

    @Override
    public IPage<OrderInfo> getPage(Page<OrderInfo> pageParam, String userId) {

        //调用mapper
        IPage<OrderInfo> page = orderInfoMapper.selectPageByUserId(pageParam,userId);
        //  获取显示用的订单状态！
        page.getRecords().stream().forEach((orderInfo)->{
            orderInfo.setOrderStatusName(OrderStatus.getStatusNameByStatus(orderInfo.getOrderStatus()));
        });
        return page;
    }

    @Override
    public void execExpiredOrder(Long orderId) {
        this.updateOrderStatus(orderId,ProcessStatus.CLOSED);
    }

    @Override
    public void updateOrderStatus(Long orderId, ProcessStatus processStatus) {
        OrderInfo orderInfo = new OrderInfo();
        orderInfo.setId(orderId);
        orderInfo.setProcessStatus(processStatus.name());
        //  可以从进程状态中获取到订单状态！
        orderInfo.setOrderStatus(processStatus.getOrderStatus().name());
        orderInfo.setUpdateTime(new Date());
        orderInfoMapper.updateById(orderInfo);
    }
}